---
author: hongbo
date: "2018-07-17"
previewImg:
badge: release
title: Announcing BuckleScript 4.0 (Part Two)
description: |
---

## New Changes

`bs-platform` 4.0.0 introduces a new runtime representation for optionals.

While beforehand `None` was represented at runtime as `0` and `Some("hello")`
as an array `["hello"]`, the new representation tries to unbox optionals as
much as possible.

Now `None` is represented as `undefined` and `Some("hello")` simply as
`"hello"`.

Generally speaking, `Some(v)` is represented as `v`, i.e. unboxed. The only
exception is when `v` itself is `None` or `Some(...(Some(None))`, in which case
a special boxed representation is used.

The construction of new values `Some(-)`, and pattern matching `| Some(-) =>
...`, perform some case analysis to decide when to box or unbox values. In the
absence of nested optionals, the result of both operations will _always_ be the
indentity.

Because of that, it's possible to use type-based optimization to avoid
performing case analysis in the first place. So while the generic function
`(x) => Some(x)` will generate code to check wheter `x` should be boxed,
the more type-specific function `(x:int) => Some(x)` is just compiled as
the identity function, as it's clear from the type that no boxing is required.

For a high-level formalization of the boxing and unboxing operations, as well
as the polymorphic comparison functions, see this
[gist](https://gist.github.com/cristianoc/791aac26f94dbded0fc137d61f4bd2a8).

One design choice was whether to represent `None` as `null` or as `undefined`.
The choice of `undefined` was made because this allows a direct mapping for
[optional labeled
arguments](https://reasonml.github.io/docs/en/function#optional-labeled-arguments).
As a consequence `null` is never boxed, so e.g. `Some(null)` is represented as
`null`.
